<?php
/**
 * Created by PhpStorm.
 * User: nightelf
 * Date: 2020/1/10
 * Time: 17:13
 */

namespace App\Http\Controllers\HumanResourceManage;


use App\Exceptions\ApiException;
use App\Http\Controllers\Controller;
use App\Http\Model\AttendanceModel;
use App\Http\Model\EmployeeModel;
use App\Http\Model\ProjectRosterModel;
use App\Http\Model\YearModel;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class EmployeeController extends Controller
{
    /**
     * 工人列表
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function lists(Request $request)
    {
        $rules = [
            'projectId' => 'required|integer',
            'professionId' => 'nullable|integer',
            'status' => 'nullable|integer',
            'isFinish' => 'nullable|integer|in:0,1',
            'yearId' => 'nullable|integer',
            'length' => 'required|integer|in:10,20,50',
            'page' => 'required|integer|min:1',
        ];
        $message = [
            'projectId.required' => '获取项目参数失败',
            'projectId.integer' => '项目参数类型错误',
            'professionId.integer' => '工种参数类型错误',
            'status.integer' => '工作状态参数类型错误',
            'isFinish.integer' => '清算状态参数类型错误',
            'isFinish.in' => '清算状态参数不正确',
            'yearId.integer' => '工程年度参数类型错误',
            'length.required' => '获取记录条数失败',
            'length.integer' => '记录条数参数类型错误',
            'length.in' => '记录条数参数值不正确',
            'page.required' => '获取起始记录位置失败',
            'page.integer' => '页码参数类型错误',
            'page.min' => '页码参数值不小于:min',
        ];
        $param = $request->only('projectId', 'professionId', 'status', 'isFinish', 'yearId', 'length', 'page', 'search');
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $yearModel = new YearModel();
            if (!empty($param['yearId'])) {
                $info = $yearModel->info(['id' => $param['yearId']]);
            } else {
                $time = date('Y-m-d H:i:s');
                $info = $yearModel->findYear($time);
            }
            if (empty($info['startTime']) && empty($info['endTime'])){
                throw new ApiException('请先设置新的工程年度', 410101);
            }
            $param['startTime'] = $info['startTime'];
            $param['endTime'] = $info['endTime'];
            $lists = $employeeModel->lists($param);
            $countLists = $employeeModel->countLists($param);
            $this->data = $this->tableFormat($lists, $countLists);
        } else {
            throw new ApiException($validator->errors()->first(), 410101);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 添加工人
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function add(Request $request)
    {
        $rules = [
            'projectId' => 'required|integer',
            'name' => 'required',
            'idcard' => 'required|size:18',
            'jobNumber' => 'required',
            'gender' => 'nullable|integer|in:1,2',
            'age' => 'nullable|integer',
            'professionId' => 'required|integer',
            'contractTime' => 'nullable|date_format:Y-m-d',
            'eduTime' => 'nullable|date_format:Y-m-d',
            'resignTime' => 'nullable|date_format:Y-m-d',
        ];
        $message = [
            'projectId.required' => '获取工人参数失败',
            'projectId.integer' => '工人参数类型错误',
            'name.required' => '请填写姓名',
            'idcard.required' => '请填写身份证号',
            'idcard.size' => '身份证号位数不正确',
            'jobNumber.required' => '请填写工号',
            'gender.integer' => '性别参数类型错误',
            'gender.in' => '性别参数不正确',
            'age.integer' => '年龄参数类型错误',
            'professionId.required' => '请选择工种',
            'professionId.integer' => '工种参数类型错误',
            'contractTime.date_format' => '签订合同时间格式不正确',
            'eduTime.date_format' => '签订合同时间格式不正确',
            'resignTime.date_format' => '离职时间格式不正确',
        ];
        $param = $request->only(['projectId', 'name', 'idcard', 'jobNumber', 'gender', 'age', 'nation', 'phone', 'bankNumber', 'homeAddress', 'professionId', 'contractTime', 'eduTime','resignTime']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $imagePath = '';
            if ($request->hasFile('image')) {
                $image = $request->file('image');
                $fileExtension = strtolower($request->image->extension());
                if (!in_array($fileExtension, ['jpg', 'jpeg', 'png', 'bmp'])) {
                    throw new ApiException('上传图片格式不正确', 410202);
                }
                $newName = time() . mt_rand(100, 999);
                if ($image->move('./upload', $newName . '.' . $fileExtension)) {
                    $imagePath = '/upload/' . $newName . '.' . $fileExtension;   //返回一个地址
                }
            }
            $param['image'] = $imagePath;
            $employeeModel = new EmployeeModel();
            $yearModel = new YearModel();
            $yearInfo = $yearModel->findYear(date('Y-m-d H:i:s'));
            //判断新工人身份证号和当前工程年度其他工人是否相同
            $result1 = $employeeModel->checkRepeat('idcard', $param['idcard'], $yearInfo['startTime'], $yearInfo['endTime']);
            //判断新工人工号和当前工程年度其他工人是否相同
            $result2 = $employeeModel->checkRepeat('jobNumber', $param['jobNumber'], $yearInfo['startTime'], $yearInfo['endTime']);
            if ($result1 > 0) {
                throw new ApiException('身份证号重复', 410203);
            }
            if ($result2 > 0) {
                throw new ApiException('工号重复', 410204);
            }
            $insertId = $employeeModel->insert($param);
            $projectRosterModel = new ProjectRosterModel();
            $projectRosterModel->roster([
                'id' => $insertId,
                'projectId' => null,
                'professionId' => $param['professionId'],
                'groupId' => null, 'hasAttendance' => 0
            ], $param['projectId']);
        } else {
            throw new ApiException($validator->errors()->first(), 410201);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 工人详情
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function info(Request $request)
    {
        $rules = [
            'id' => 'required|integer',
        ];
        $message = [
            'id.required' => '获取工人参数失败',
            'id.integer' => '工人参数类型错误',
        ];
        $param = $request->only('id');
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $this->data = $employeeModel->info($param);
        } else {
            throw new ApiException($validator->errors()->first(), 410301);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 工人信息编辑
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function edit(Request $request)
    {
        $rules = [
            'id' => 'required|integer',
            'projectId' => 'required|integer',
            'name' => 'required',
            'idcard' => 'required|size:18',
            'jobNumber' => 'required',
            'gender' => 'nullable|integer|in:0,1,2',
            'age' => 'nullable|integer',
            'professionId' => 'required|integer',
            'isContract' => 'nullable|integer|in:0,1',
            'contractTime' => 'nullable|date_format:Y-m-d',
            'isEdu' => 'nullable|integer|in:0,1',
            'eduTime' => 'nullable|date_format:Y-m-d',
            'resignTime' => 'nullable|date_format:Y-m-d',
        ];
        $message = [
            'id.required' => '获取工人参数失败',
            'id.integer' => '工人参数类型错误',
            'projectId.required' => '获取项目参数失败',
            'projectId.integer' => '项目参数类型错误',
            'name.required' => '请填写姓名',
            'idcard.required' => '请填写身份证号',
            'idcard.size' => '身份证号位数不正确',
            'jobNumber.required' => '请填写工号',
            'gender.integer' => '性别参数类型错误',
            'gender.in' => '性别参数不正确',
            'age.integer' => '年龄参数类型错误',
            'professionId.required' => '请选择工种',
            'professionId.integer' => '工种参数类型错误',
            'contractTime.date_format' => '签订合同时间格式不正确',
            'eduTime.date_format' => '签订合同时间格式不正确',
            'resignTime.date_format' => '离职时间格式不正确',
        ];
        $param = $request->only(['id', 'projectId', 'professionId', 'name', 'idcard', 'jobNumber', 'gender', 'age', 'nation', 'phone', 'bankNumber', 'homeAddress', 'contractTime', 'eduTime','resignTime']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $imagePath = '';
            if ($request->hasFile('image')) {
                $image = $request->file('image');
                $fileExtension = strtolower($request->image->extension());
                if (!in_array($fileExtension, ['jpg', 'jpeg', 'png', 'bmp'])) {
                    throw new ApiException('上传图片格式不正确', 410402);
                }
                $newName = time() . mt_rand(100, 999);
                if ($image->move('./upload', $newName . '.' . $fileExtension)) {
                    $imagePath = '/upload/' . $newName . '.' . $fileExtension;   //返回一个地址
                }
            }
            $param['image'] = $imagePath;
            $employeeModel = new EmployeeModel();
            $id = $param['id'];
            unset($param['id']);
            $info = $employeeModel->info(['id' => $id]);
            if (!empty($info['image']) && fileExists('.' . $info['image'])) {
                unlink('.' . $info['image']);
            }
            if (!empty($param['resignTime'])) {
                $param['status'] = 4;
            }else{
                $param['status'] = 1;
            }
            $employeeModel->update(['id' => $id], $param);
            if ($info['projectId'] != $param['projectId']) {
                $projectRosterModel = new ProjectRosterModel();
                $projectRosterModel->roster($info, $param['projectId']);
            }
        } else {
            throw new ApiException($validator->errors()->first(), 410401);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 批量更改工人工作状态（工人离职）
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function batchChangeStatus(Request $request)
    {
        $rules = [
            'ids' => 'required|array',
            'status' => 'required|integer|in:4'
        ];
        $message = [
            'ids.required' => '获取工人参数组失败',
            'ids.array' => '工人参数类型错误',
            'status.required' => '请选择工作状态',
            'status.integer' => '工作状态参数类型错误',
            'status.in' => '工作状态参数值不正确'
        ];
        $param = $request->only(['ids', 'status']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $employeeModel->batchUpdate($param['ids'], ['status' => $param['status']]);
        } else {
            throw new ApiException($validator->errors()->first(), 410501);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 工人项目调配
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function batchChangeProject(Request $request)
    {
        $rules = [
            'ids' => 'required|array',
            'projectId' => 'required|integer'
        ];
        $message = [
            'ids.required' => '获取工人参数组失败',
            'ids.array' => '工人参数类型错误',
            'projectId.required' => '请选择工作状态',
            'projectId.integer' => '工作状态参数类型错误',
        ];
        $param = $request->only(['ids', 'projectId']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $projectRosterModel = new ProjectRosterModel();
            //验证所有选中的工人是否是在岗状态
            $i = 0;
            foreach ($param['ids'] as $id) {
                $info = $employeeModel->info(['id' => $id]);
                if ($info['status'] != 4) {
                    $employeeModel->update(['id' => $id], ['projectId' => $param['projectId']]);
                    $projectRosterModel->roster($info, $param['projectId']);
                    $i++;
                }
            }
            $this->msg = '共选中' . count($param['ids']) . '名工人，成功调动' . $i . '名工人至所选项目';
        } else {
            throw new ApiException($validator->errors()->first(), 410601);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 公司考勤日历
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function attendanceList(Request $request)
    {
        $rules = [
            'projectId' => 'required|integer',
            'professionId' => 'nullable|integer',
            'month' => 'nullable|date_format:Y-m',
        ];
        $message = [
            'projectId.required' => '获取项目参数失败',
            'projectId.integer' => '项目参数类型错误',
            'professionId.integer' => '工种参数类型错误',
            'month.date_format' => '月份参数格式不正确',
        ];
        $param = $request->only(['projectId', 'month', 'professionId']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $this->data = $employeeModel->attendanceList($param);
        } else {
            throw new ApiException($validator->errors()->first(), 410701);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 增加考勤人员
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function supplement(Request $request)
    {
        $rules = [
            'employeeId' => 'required|integer',
        ];
        $message = [
            'employeeId.required' => '获取工人参数失败',
            'employeeId.integer' => '工人参数类型错误',
        ];
        $param = $request->only(['employeeId']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            //追加工人当前的projectId
            $employeeModel = new EmployeeModel();
            $projectRosterModel = new ProjectRosterModel();
            $info = $employeeModel->info(['id' => $param['employeeId']]);
            $employeeModel->update(['id' => $param['employeeId']], ['hasAttendance' => 1]);
            $roster = $projectRosterModel->info(['employeeId' => $info['id'], 'projectId' => $info['projectId']]);
            if (empty($roster)) {
                $projectRosterModel->insert(['employeeId' => $info['id'],
                    'projectId' => $info['projectId'],
                    'professionId' => $info['professionId'],
                    'groupId' => $info['groupId'],
                    'isAttendance' => 1,
                    'entryTime' => date('Y-m-d H:i:s'),
                    'status' => 1]);
            } else {
                $projectRosterModel->update(['employeeId' => $info['id'], 'projectId' => $info['projectId']], ['isAttendance' => 1,'status' => 1]);
            }

        } else {
            throw new ApiException($validator->errors()->first(), 410801);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 保存考勤
     *
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function addAttendance(Request $request)
    {
        $rules = [
            'employeeId' => 'required|integer',
            'projectId' => 'required|integer',
            'day' => 'required|date_format:Y-m-d',
            'length' => 'required|numeric'
        ];
        $message = [
            'employeeId.required' => '获取工人参数失败',
            'employeeId.integer' => '工人参数类型错误',
            'projectId.required' => '获取项目参数失败',
            'projectId.integer' => '项目参数类型错误',
            'day.required' => '请选择考勤日期',
            'day.date_format' => '考勤日期格式不正确',
            'length.required' => '请填写工作时长',
            'length.numeric' => '工作时长类型错误',
        ];
        $data = $request->only(['data']);
        if (!empty($data['data'])) {
            $adminId = $request->session()->get('adminId');
            $employeeModel = new EmployeeModel();
            foreach ($data['data'] as $key => $d) {
                $validator = Validator::make($d, $rules, $message);
                if ($validator->fails()) {
                    throw new ApiException($validator->errors()->first(), 410901);
                }

                $info = $employeeModel->info(['id' => $d['employeeId']]);
                if ($d['projectId'] != $info['projectId']) {
                    throw new ApiException('工人不在当前项目，不能补录考勤', 410902);
                }

                if (substr($d['day'], 0, 7) != date('Y-m')) {
                    throw new ApiException('非当前月份考勤，不能进行补录。', 410903);
                }

                if ($d['day'] > date('Y-m-d')) {
                    throw new ApiException('考勤日期不能超过当前时间', 410904);
                }

                $data['data'][$key]['adminId'] = $adminId;
                $data['data'][$key]['isCurrent'] = $d['day'] == date('Y-m-d') ? 1 : 0;
            }

            $attendanceModel = new AttendanceModel();
            $result = $attendanceModel->insert($data);
            if (!$result) {
                throw new ApiException('保存失败', 410905);
            }
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function dayValueLists(Request $request)
    {
        $rules = [
            'projectId' => 'nullable|integer',
            'professionId' => 'nullable|integer',
            'length' => 'required|integer|in:10,20,50',
            'page' => 'required|integer|min:0',
        ];
        $message = [
            'projectId.integer' => '项目参数类型错误',
            'professionId.integer' => '工种参数类型错误',
            'length.required' => '获取记录条数失败',
            'length.integer' => '记录条数参数类型错误',
            'length.in' => '记录条数参数值不正确',
            'page.required' => '获取起始记录位置失败',
            'page.integer' => '页码参数类型错误',
            'page.min' => '页码参数值不小于:min',
        ];
        $param = $request->only(['projectId', 'professionId', 'search', 'length', 'page']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $lists = $employeeModel->dayValueLists($param);
            $countLists = $employeeModel->countDayValueLists($param);
            $this->data = $this->tableFormat($lists, $countLists);
        } else {
            throw new ApiException($validator->errors()->first(), 411001);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 批量保存考勤
     * @param Request $request
     * @return \Illuminate\Http\Response
     */
    public function batchEditDayValue(Request $request)
    {
        $param = $request->only(['data']);
        $rules = [
            'employeeId' => 'required|integer',
            'dayValue' => 'required|integer',
        ];
        $i = 0;
        foreach ($param['data'] as $d) {
            $validator = Validator::make($d, $rules);
            if ($validator->passes()) {
                $employeeModel = new EmployeeModel();
                $info = $employeeModel->info(['id' => $d['employeeId']]);
                if ($info['hasAttendance'] == 1) {
                    $employeeModel->update(['id' => $d['employeeId']], ['dayValue' => $d['dayValue']]);
                    $i++;
                }
            }
        }
        $this->msg = '共' . $i . '个日工值保存成功';
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 删除工人信息
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function delete(Request $request)
    {
        $rules = [
            'id' => 'required|integer',
        ];
        $message = [
            'id.required' => '获取工人参数失败',
            'id.integer' => '工人参数类型错误',
        ];
        $param = $request->only(['id']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $result = $employeeModel->delete($param['id']);
            if (is_string($result)) {
                throw new ApiException('删除失败，该工人已经参与考勤或分账等', 411102);
            }
        } else {
            throw new ApiException($validator->errors()->first(), 411101);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function search(Request $request)
    {
        $rules = [
            'search' => 'required',
//            'projectId' => 'required|integer'
        ];
        $message = [
            'search.required' => '请填写工人姓名或工号',
//            'projectId.required' => '获取项目参数失败',
//            'projectId.integer' => '项目参数类型错误',
        ];
        $param = $request->only(['search']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $employeeModel = new EmployeeModel();
            $yearModel = new YearModel();
            if (!empty($param['yearId'])) {
                $info = $yearModel->info(['id' => $param['yearId']]);
            } else {
                $time = date('Y-m-d H:i:s');
                $info = $yearModel->findYear($time);
            }
            $param['startTime'] = $info['startTime'];
            $param['endTime'] = $info['endTime'];
            $this->data = $employeeModel->lists($param, true);
        } else {
            throw new ApiException($validator->errors()->first(), 411201);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 项目考勤日历
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws \Exception
     */
    public function attendance(Request $request)
    {
        $rules = [
            'projectId' => 'required|integer',
//            'professionId' => 'nullable|integer',
            'month' => 'nullable|date_format:Y-m',
        ];
        $message = [
            'projectId.required' => '获取项目参数失败',
            'projectId.integer' => '项目参数类型错误',
//            'professionId.integer' => '工种参数类型错误',
            'month.date_format' => '月份参数格式不正确',
        ];
        $param = $request->only(['projectId', 'month']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
           if ($param['month'] >= date('Y-m')){
               $projectRosterModel = new ProjectRosterModel();
               $this->data = $projectRosterModel->attendance($param);
           }else{
                $employeeModel = new EmployeeModel();
                $this->data = $employeeModel->attendanceList($param);
           }

        } else {
            throw new ApiException($validator->errors()->first(), 411301);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }

    /**
     * 删除工人信息
     * @param Request $request
     * @return \Illuminate\Http\Response
     * @throws ApiException
     */
    public function deleteAttendance(Request $request)
    {
        $rules = [
            'id' => 'required|integer',
        ];
        $message = [
            'id.required' => '获取考勤参数失败',
            'id.integer' => '考勤参数类型错误',
        ];
        $param = $request->only(['id']);
        $validator = Validator::make($param, $rules, $message);
        if ($validator->passes()) {
            $attendanceModel = new AttendanceModel();
            $result = $attendanceModel->delete($param);
            if (!$result) {
                throw new ApiException('删除失败', 411402);
            }
        } else {
            throw new ApiException($validator->errors()->first(), 411401);
        }
        return $this->ajaxResult($this->code, $this->msg, $this->data);
    }
}